package com.cy.module;

import com.cy.ext.plugin.route.ControllerBind;
import com.cy.model.Account;
import com.cy.model.AccountRole;
import com.cy.model.Menu;
import com.cy.model.Permission;
import com.google.common.collect.Lists;
import com.jfinal.aop.Before;
import com.jfinal.kit.JsonKit;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.tx.Tx;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@ControllerBind(controllerKey = "/clmp/accountRole")
public class AccountRoleController extends WebApiController {
    @Override
    public void index() {
        AccountRole accountRole = getModel(AccountRole.class);
        int page = getParaToInt("pageIndex");
        int pageSize = getParaToInt("limit");
        Page<AccountRole> accountRolePage = AccountRole.dao.paginate(page, pageSize, AccountRole.SELECT_ALL, accountRole);
        renderBuiPage(accountRolePage, 200);
    }

    @Override
    public void update() {
        int id = getParaToInt();
        AccountRole tempAccountRole = getModel(AccountRole.class);
        AccountRole accountRole = AccountRole.dao.findById(id);
        accountRole.cover(tempAccountRole);

        if (accountRole.update()) {
            renderSuccess();
        } else {
            renderFail();
        }
    }

    @Override
    public void save() {
        AccountRole accountRole = getModel(AccountRole.class);
        accountRole.setCreateTime(new Date());
        if (accountRole.save()) {
            renderSuccess();
        } else {
            renderFail();
        }
    }

    @Override
    public void delete() {
        String[] ids = getPara().split("-");
        for (String id : ids) {
            AccountRole.dao.deleteById(id);
        }
        renderSuccess();
    }

    /**
     * 分页查询角色用户
     */
    public void getAccountByRole(){
        String roleId = getPara("roleId");
        Account account = getModel(Account.class);
        int page = getParaToInt("pageIndex");
        int pageSize = getParaToInt("limit");
        Page<Account> devicePage = Account.dao.pageAccountByRole(page, pageSize, account, roleId);
        renderBuiPage(devicePage, 200);
    }

    /**
     * 获取权限树
     */
    public void getPermTree(){
        Long roleId = getParaToLong("roleId");
        Integer type = getParaToInt("type");
        //角色所有菜单（权限）
        List<Menu> rolesMenus = Menu.dao.findByRoleAndType(roleId, type);

        //所有菜单
        List<Object> result = new ArrayList<>();
        for (Menu rootMenu : Menu.dao.findByParent(null, type)){
            Map<String, Object> menuMap = new LinkedHashMap<>(4);
            menuMap.put("id", rootMenu.getId());
            menuMap.put("text", rootMenu.getName());
            menuMap.put("expanded", true);
            List<Map<String, Object>> submenus = processSubmenuJson(rootMenu, rolesMenus);
            if (submenus.size() > 0){
                menuMap.put("children", submenus);
            }
            result.add(menuMap);
        }
        String resultJson = JsonKit.toJson(result, 20);
        renderJson(resultJson);
    }

    /**
     * 递归处理子菜单JSON
     * @param root 根菜单
     * @param rolesMenu 角色所有菜单（权限）
     * @return 所有子菜单Map集合
     */
    private List<Map<String, Object>> processSubmenuJson(Menu root, List<Menu> rolesMenus){
        List<Menu> subs = root.getChildren();
        List<Map<String, Object>> menuList = new ArrayList<>();
        for (Menu sub : subs){
            Map<String, Object> map = new LinkedHashMap<>(5);
            map.put("id", sub.getId());
            map.put("text", sub.getName());
            map.put("expanded", true);

            List<Map<String, Object>> children = processSubmenuJson(sub, rolesMenus);
            if (children.size() > 0){
                map.put("children", children);
            } else {
                for (Menu rolesMenu : rolesMenus){
                    if (rolesMenu.getId().equals(sub.getId())){
                        map.put("checked", true);
                        break;
                    }
                }
            }
            menuList.add(map);
        }
        return menuList;
    }

    /**
     * 修改权限
     */
    @Before(Tx.class)
    public void updatePerm(){
        Long roleId = getParaToLong("roleId");
        Integer type = getParaToInt("type");
        String idsStr = getPara("ids");
        List<String> ids = StringUtils.isNotBlank(idsStr) ? Lists.newArrayList(idsStr.split(",")) : new ArrayList<String>(0);

        List<Menu> rolesMenus = Menu.dao.findByRoleAndType(roleId, type);

        //Menu对象转换成ID
        List<String> rolesMenuIds = new ArrayList<>(rolesMenus.size());
        for (Menu rolesMenu : rolesMenus){
            rolesMenuIds.add(rolesMenu.getId().toString());
        }

        //排除相同元素不做修改
        for (Iterator<String> menuIdsIt = rolesMenuIds.listIterator(); menuIdsIt.hasNext();){
            String rolesMenuId = menuIdsIt.next();
            for(Iterator<String> idsIt = ids.listIterator(); idsIt.hasNext();){
                String id = idsIt.next();
                if (rolesMenuId.equals(id)){
                    menuIdsIt.remove();
                    idsIt.remove();
                    break;
                }
            }
        }

        try {
            //删除原有多余的权限
            if (rolesMenuIds.size() > 0)
                Permission.dao.deleteByRoleAndMenu(new Long[]{roleId}, rolesMenuIds.toArray());
            //新增不存在的权限
            for (String id : ids){
                new Permission().setAccountRoleId(roleId).setMenuId(Long.valueOf(id)).save();
            }
            renderSuccess();
        } catch (Exception e){
            e.printStackTrace();
            renderFail();
        }
    }
}